package ast;

import java.util.ArrayList;

import symbol.astPreprocessContext;

public class PrimaryDataSignature extends DataSignature {
	// type包括：int, double, long, longlong, char, string, func, 自定义的类
	public String dataType;
	// 匿名常量不需要
	public String name;
	// 匿名常量需要填写这个值（用户自己定义的1，2.5，‘c’, true之类的）
	public Object value;
	
	public String ptrTransform;
	public String funckey;
	
	public Boolean isMethod = false;
	public String methodName;
	
	public Boolean isFuncAttr = false;
	
	public void updateFunckey(ArrayList<String> paramsType) {
		// 类的方法也需要更新funckey（打一下补丁，因为类的方法是complex，不能更新funckey）
		if (isMethod == true) {
			String result = "_";
			result += methodName + "_";
			for (String type: paramsType) {
				result += type + "_";
			}
			result = result.replace("<", "_");
			result = result.replace(">", "");
			funckey = result;
//			System.out.println(funckey + "***");
			return;
		}
//		System.out.println(name);
		String result = "_";
		if (astPreprocessContext.getClassList().contains(name)) {
			// 类的构造器
			result += name + "_constructor_";
			for (String type: paramsType) {
				result += type + "_";
			}
			result = result.replace("<", "_");
			result = result.replace(">", "");
			funckey = result;
			return;
		} else {
			if (!astPreprocessContext.isDefinedFunction(name)) {
				// 不是函数.直接赋值
//				System.out.println("****");
				funckey = name;
				return;
			}
			result += name + "_";
			for (String type: paramsType) {
				result += type + "_";
			}
			result = result.replace("<", "_");
			result = result.replace(">", "");
			funckey = result;
		}
		// 不是重载函数，也不是构造器，一律不要
		if (astPreprocessContext.isNoReload(name)) funckey = name;
//		System.out.println(funckey);
	}
	
	public void updatePtrTransform(ArrayList<String> paramsType) {
		// 如果是函数,不需要类型转换
		String result = "(" + getTypeC(dataType.substring(5, dataType.length() - 1)) + "(*) (";
		for (int i = 0;i < paramsType.size();i++) {
			result += getTypeC(paramsType.get(i));
			if (i != paramsType.size() - 1) {
				result += ", ";
			}
		}
		result += "))";
		ptrTransform = result;
	}
	
	public String getDeclString() {
		// 声明和函数返回声明都用这个
		if (dataType.length() >= 4 && dataType.substring(0, 4).contains("func")) return "void*";
		if (dataType.contains("int") || dataType.contains("double") || (dataType.contains("long") && !dataType.contains("longlong"))) return dataType;
		if (dataType.contains("bool")) return "int";
		String realType = dataType;
		if (dataType.contains("longlong")) realType = "long long";
		else if (dataType.contains("string")) realType = "char";
		else if (dataType.contains("char")) realType = "char";
		else realType = "struct " + dataType + "*";
//		System.out.println(dataType + "->" + realType);
		return realType;
	}
	
	public String getTypeC(String t) {
		System.out.print(name);
		String[] typeInfo = t.split("_");
		assert typeInfo.length > 0;
		String type_c = typeInfo[0];
		if (typeInfo[0].equals("bool")) type_c = "int";
		else if (typeInfo[0].equals("longlong")) type_c = "long long";
		else if (typeInfo[0].equals("string")) type_c = "char[]";
		else if (typeInfo[0].contains("func")) type_c = "void*";
		else if (typeInfo[0].contains("char")) type_c = "char";
		else if (astPreprocessContext.getClassList().contains(typeInfo[0])) type_c = "struct " + typeInfo[0] + "*";
//		System.out.println(type_c);
		return type_c;
	}
	
	public String toStringWithType() {
		String[] typeInfo = dataType.split("_");
		assert typeInfo.length > 0;
		String type_c = typeInfo[0];
		if (typeInfo[0].equals("bool")) type_c = "int";
		else if (typeInfo[0].equals("longlong")) type_c = "long long";
		else if (typeInfo[0].equals("string")) type_c = "char[]";
		else if (typeInfo[0].contains("func")) type_c = "void*";
		else if (typeInfo[0].contains("char")) type_c = "char";
		else if (astPreprocessContext.getClassList().contains(typeInfo[0])) type_c = "struct " + typeInfo[0] + "*";
		return type_c + " " + name;
	}

	public String toString() {
		// 仅仅是变量本身(强制类型转换)
		if (this.name != null) {
			if (ptrTransform != null && funckey != null) {
				return "(" + ptrTransform + " " + funckey + ")";
			} else if (ptrTransform != null && funckey == null) {
				return "(" + ptrTransform + " " + name + ")";
			} else if (ptrTransform == null && funckey != null) {
				return funckey;
			} else if (ptrTransform == null && funckey == null) {
				return name;
			}
		}
		// 匿名变量
		// 如果是字符，在前后加上单引号
		if (dataType == "char") return "\'" + value.toString() + "\'";
		if (dataType == "string") return value.toString();
		// 如果是bool变量，转换为1和0
		else if (dataType == "bool") {
			if (value.toString() == "true") return "1";
			else if (value.toString() == "false") return "0";
			else return null;
		}
		// 否则直接返回
		else return value.toString();
	}
	
	public void preprocess(AstItem father) {
		// （1）先判断是不是构造器
		// （2）再查局部符号表
		// （3）再判断是不是普通函数（类的方法应该不考虑在内） 查函数类型表
		// （4）最后查全局符号表
		astPreprocessContext.getContext();
//		System.out.println(value);
//		if (value != null) System.out.println(value.getClass());
		if (name == null) {
			if (value instanceof Integer) {
				this.dataType = "int";
			} else if (value instanceof Long) {
				this.dataType = "longlong";
			} else if (value instanceof Float || value instanceof Double) {
				this.dataType = "double";
			} else if (value instanceof Character) {
				this.dataType = "char";
			} else if (value instanceof String) {
				this.dataType = "string";
			} else if (value instanceof Boolean) {
				this.dataType = "bool";
			}
		}
//		System.out.println(name + "&&&");
//		System.out.println(astPreprocessContext.toDebugString());
		if (this.dataType == null) {
			if (astPreprocessContext.getClassList().contains(name)) {
				// 构造器
				this.dataType = name;
			} else {
				if (astPreprocessContext.getNowSymbolTables().containsSymbol(name)) {
					// 局部符号表
					this.dataType = astPreprocessContext.getNowSymbolTables().getSymbolInfo(name).typeToString();
				} else if (astPreprocessContext.getFuncType(name) != null) {
					// 普通函数
					this.dataType = astPreprocessContext.getFuncType(name);
				} else if (astPreprocessContext.getGlobalSymbolTables().getSymbolInfo(name) != null) {
					// 全局符号表
//					System.out.println(name + ")))");
//					System.out.println(astPreprocessContext.toDebugString());
					this.dataType = astPreprocessContext.getGlobalSymbolTables().getSymbolInfo(name).typeToString();
				} else {
					// 类的定义里面
					String classname = astPreprocessContext.getNowClass();
					if (astPreprocessContext.getGlobalSymbolTables().getSymbolInfo(classname + "#" + name) != null) {
						// 类的属性
//						System.out.println(name + "////");
						this.dataType = astPreprocessContext.getGlobalSymbolTables().getSymbolInfo(classname + "#" + name).typeToString();
					} else {
						// 类的方法
						this.dataType = astPreprocessContext.getFuncType(classname + "." + name);
					}
				}
			}
		}
		assert this.dataType != null;
	}

	@Override
	public String toJsonString() {
		String json = "{";
		json += "\"Type\": \"DataSignature-" + type.toString() + "\",";
		json += "\"DataType\": \"" + dataType + "\",";
		json += "\"Name\": \"" + name + "\",";
		json += "\"Value\": " + (value != null ? value.toString() : "\"\"");
		json += "}";
		return json;
	}
}
